const logger = require('./logger');

/**
 * 简单的内存缓存实现
 * 生产环境建议使用 Redis
 */
class MemoryCache {
  constructor(options = {}) {
    this.cache = new Map();
    this.ttl = options.ttl || 60 * 1000; // 默认 60 秒
    this.maxSize = options.maxSize || 100; // 最大缓存条目数
    this.hits = 0;
    this.misses = 0;
    
    // 定期清理过期缓存
    this.cleanupInterval = setInterval(() => this.cleanup(), 60 * 1000);
  }

  /**
   * 生成缓存键
   */
  generateKey(prefix, params = {}) {
    const sortedParams = Object.keys(params)
      .sort()
      .map(key => `${key}:${params[key]}`)
      .join('|');
    return `${prefix}:${sortedParams}`;
  }

  /**
   * 获取缓存
   */
  get(key) {
    const item = this.cache.get(key);
    
    if (!item) {
      this.misses++;
      return null;
    }
    
    // 检查是否过期
    if (Date.now() > item.expiry) {
      this.cache.delete(key);
      this.misses++;
      return null;
    }
    
    this.hits++;
    return item.value;
  }

  /**
   * 设置缓存
   */
  set(key, value, ttl = this.ttl) {
    // 检查缓存大小限制
    if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
      // 删除最旧的条目
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey);
    }
    
    this.cache.set(key, {
      value,
      expiry: Date.now() + ttl
    });
  }

  /**
   * 删除缓存
   */
  delete(key) {
    return this.cache.delete(key);
  }

  /**
   * 清空所有缓存
   */
  clear() {
    this.cache.clear();
    this.hits = 0;
    this.misses = 0;
    logger.info('缓存已清空');
  }

  /**
   * 根据前缀删除缓存
   */
  deleteByPrefix(prefix) {
    let count = 0;
    for (const key of this.cache.keys()) {
      if (key.startsWith(prefix)) {
        this.cache.delete(key);
        count++;
      }
    }
    logger.info(`删除了 ${count} 个缓存条目`, { prefix });
    return count;
  }

  /**
   * 清理过期缓存
   */
  cleanup() {
    const now = Date.now();
    let count = 0;
    
    for (const [key, item] of this.cache.entries()) {
      if (now > item.expiry) {
        this.cache.delete(key);
        count++;
      }
    }
    
    if (count > 0) {
      logger.debug(`清理了 ${count} 个过期缓存条目`);
    }
  }

  /**
   * 获取缓存统计信息
   */
  getStats() {
    const total = this.hits + this.misses;
    return {
      hits: this.hits,
      misses: this.misses,
      hitRate: total > 0 ? (this.hits / total * 100).toFixed(2) + '%' : '0%',
      size: this.cache.size,
      maxSize: this.maxSize
    };
  }

  /**
   * 销毁缓存
   */
  destroy() {
    clearInterval(this.cleanupInterval);
    this.cache.clear();
  }
}

/**
 * 缓存中间件工厂函数
 */
const cacheMiddleware = (cache, options = {}) => {
  const {
    keyGenerator = (req) => `${req.method}:${req.originalUrl}`,
    ttl = 60 * 1000,
    condition = () => true
  } = options;

  return (req, res, next) => {
    // 只缓存 GET 请求
    if (req.method !== 'GET' || !condition(req)) {
      return next();
    }

    const key = keyGenerator(req);
    const cachedResponse = cache.get(key);

    if (cachedResponse) {
      logger.debug('命中缓存', { key });
      return res.json(cachedResponse);
    }

    // 保存原始 json 方法
    const originalJson = res.json.bind(res);

    // 重写 json 方法以缓存响应
    res.json = function(data) {
      // 只缓存成功的响应
      if (res.statusCode === 200) {
        cache.set(key, data, ttl);
        logger.debug('设置缓存', { key });
      }
      return originalJson(data);
    };

    next();
  };
};

// 创建默认缓存实例
const defaultCache = new MemoryCache({
  ttl: 5 * 60 * 1000, // 5 分钟
  maxSize: 100
});

// 创建视频列表缓存
const videoListCache = new MemoryCache({
  ttl: 2 * 60 * 1000, // 2 分钟
  maxSize: 50
});

// 创建分类缓存（更长的缓存时间）
const categoryCache = new MemoryCache({
  ttl: 10 * 60 * 1000, // 10 分钟
  maxSize: 20
});

module.exports = {
  MemoryCache,
  cacheMiddleware,
  defaultCache,
  videoListCache,
  categoryCache
};

